/**
 * 设置管理工具
 * 使用 @lazycatcloud/minidb 保存设置
 */

import { MiniDB } from '@lazycatcloud/minidb'

export type SidebarPosition = 'left' | 'right' | 'top' | 'bottom'
export type WindowMode = 'single' | 'multi'

export interface KeyboardShortcut {
  key: string // 主键，如 'k', 'K', 'Enter'
  ctrl?: boolean
  shift?: boolean
  alt?: boolean
  meta?: boolean
}

interface Settings {
  sidebarPositions: SidebarPosition[]
  windowMode: WindowMode
  quickSwitchShortcut?: KeyboardShortcut // 快捷切换面板的快捷键
}

// 初始化 MiniDB 实例
const db = new MiniDB()
const collection = db.getCollection('settings')

const SETTINGS_ID = 'main'

// 内存中的当前设置缓存（避免每次都读取数据库）
let currentSettingsCache: Settings | null = null

const DEFAULT_SETTINGS: Settings = {
  sidebarPositions: ['left'],
  windowMode: 'single',
  quickSwitchShortcut: {
    key: 'k',
    ctrl: true
  }
}

function normalizeSidebarPositions(value: unknown): SidebarPosition[] {
  if (Array.isArray(value)) {
    const filtered = value.filter((pos): pos is SidebarPosition =>
      ['left', 'right', 'top', 'bottom'].includes(pos as SidebarPosition)
    )
    return filtered.length > 0 ? filtered : [...DEFAULT_SETTINGS.sidebarPositions]
  }

  if (typeof value === 'string') {
    try {
      const parsed = JSON.parse(value)
      if (Array.isArray(parsed)) {
        const filtered = parsed.filter((pos): pos is SidebarPosition =>
          ['left', 'right', 'top', 'bottom'].includes(pos as SidebarPosition)
        )
        return filtered.length > 0 ? filtered : [...DEFAULT_SETTINGS.sidebarPositions]
      }
    } catch {
      // ignore, fallback to default
    }
  }

  return [...DEFAULT_SETTINGS.sidebarPositions]
}

function normalizeKeyboardShortcut(value: unknown): KeyboardShortcut {
  if (value && typeof value === 'object' && 'key' in value) {
    const shortcut = value as any
    return {
      key: typeof shortcut.key === 'string' ? shortcut.key : 'k',
      ctrl: Boolean(shortcut.ctrl),
      shift: Boolean(shortcut.shift),
      alt: Boolean(shortcut.alt),
      meta: Boolean(shortcut.meta)
    }
  }
  return { ...DEFAULT_SETTINGS.quickSwitchShortcut! }
}

/**
 * 加载设置
 * 参考 appHistory.ts 的实现方式：查询所有记录，选择最新的
 * @param forceReload 是否强制重新加载（忽略缓存）
 */
export async function loadSettings(forceReload = false): Promise<Settings> {
  if (!forceReload && currentSettingsCache) {
    return currentSettingsCache
  }

  try {
    // 如果强制重新加载，清除缓存
    if (forceReload) {
      currentSettingsCache = null
    }
    
    // 查询所有 id 为 SETTINGS_ID 的记录
    const docs = await collection.find({ id: SETTINGS_ID }).fetch()
    
    // 如果有记录，选择最新的（按 _id 排序，取最新的）
    if (docs && docs.length > 0) {
      // 按 _id 排序，取最新的
      const target = docs.sort((a: any, b: any) => {
        return String(b._id || '').localeCompare(String(a._id || ''))
      })[0]

      const settings: Settings = {
        sidebarPositions: normalizeSidebarPositions((target as any).sidebarPositions),
        windowMode: (target as any).windowMode === 'multi' ? 'multi' : 'single',
        quickSwitchShortcut: normalizeKeyboardShortcut((target as any).quickSwitchShortcut)
      }

      currentSettingsCache = settings
      
      // 如果发现有重复记录，异步清理（不阻塞加载）
      if (docs.length > 1) {
        clearDuplicateSettings().catch(err => {
          console.warn('清理重复设置记录失败:', err)
        })
      }
      
      return settings
    }

    // 如果还没有设置记录，则创建默认记录并返回默认值
    const defaultSettings: Settings = {
      sidebarPositions: [...DEFAULT_SETTINGS.sidebarPositions],
      windowMode: DEFAULT_SETTINGS.windowMode,
      quickSwitchShortcut: { ...DEFAULT_SETTINGS.quickSwitchShortcut! }
    }

    // 使用 id: SETTINGS_ID 作为唯一标识创建默认记录
    await collection.upsert({
      id: SETTINGS_ID,
      sidebarPositions: defaultSettings.sidebarPositions,
      windowMode: defaultSettings.windowMode
    })

    currentSettingsCache = defaultSettings
    return defaultSettings
  } catch (error) {
    console.error('读取设置失败:', error)
    currentSettingsCache = { ...DEFAULT_SETTINGS }
    return { ...DEFAULT_SETTINGS }
  }
}

/**
 * 保存设置
 * 重构：先查询现有记录，如果有则使用 upsert(doc, base) 更新，如果没有则插入
 */
export async function saveSettings(settings: Partial<Settings>): Promise<void> {
  try {
    // 如果缓存存在，使用缓存；否则加载
    let current: Settings
    if (currentSettingsCache) {
      current = currentSettingsCache
    } else {
      current = await loadSettings()
      currentSettingsCache = current
    }
    
    // 合并设置
    const updated: Settings = {
      ...current,
      ...settings
    }
    
    // 确保 sidebarPositions 是数组
    if (!Array.isArray(updated.sidebarPositions)) {
      updated.sidebarPositions = [...DEFAULT_SETTINGS.sidebarPositions]
    }
    
    // 更新缓存
    currentSettingsCache = updated
    
    // 查询现有记录
    const existingDocs = await collection.find({ id: SETTINGS_ID }).fetch()
    let existingDoc: any = null
    
    if (existingDocs && existingDocs.length > 0) {
      // 找到最新的记录作为 base
      existingDoc = existingDocs.sort((a: any, b: any) => {
        return String(b._id || '').localeCompare(String(a._id || ''))
      })[0]
    }
    
    // 准备要保存的文档
    const docToSave = {
      id: SETTINGS_ID,
      sidebarPositions: updated.sidebarPositions,
      windowMode: updated.windowMode,
      quickSwitchShortcut: updated.quickSwitchShortcut || DEFAULT_SETTINGS.quickSwitchShortcut
    }
    
    // 如果有现有记录，使用 upsert(doc, base) 形式来更新
    // 如果没有现有记录，直接使用 upsert(doc) 来插入
    if (existingDoc) {
      // 更新现有记录：传入 base 参数，upsert 会更新而不是插入
      await collection.upsert(docToSave, existingDoc)
    } else {
      // 插入新记录
      await collection.upsert(docToSave)
    }
    
    // 保存后立即清理重复记录（确保数据库中只有一条记录）
    // 异步清理，不阻塞保存操作
    clearDuplicateSettings().catch(err => {
      console.warn('清理重复设置记录时出错:', err)
    })
  } catch (error) {
    console.error('保存设置失败:', error)
    throw error
  }
}

/**
 * 加载设置（带缓存）
 */
export async function loadSettingsWithCache(): Promise<Settings> {
  if (currentSettingsCache) {
    return currentSettingsCache
  }
  const settings = await loadSettings()
  currentSettingsCache = settings
  return settings
}

/**
 * 保存侧边栏位置设置
 */
export async function saveSidebarPositions(positions: SidebarPosition[]): Promise<void> {
  await saveSettings({ sidebarPositions: positions })
}

/**
 * 保存窗口模式设置
 */
export async function saveWindowMode(mode: WindowMode): Promise<void> {
  await saveSettings({ windowMode: mode })
}

/**
 * 保存快捷切换面板快捷键设置
 */
export async function saveQuickSwitchShortcut(shortcut: KeyboardShortcut): Promise<void> {
  await saveSettings({ quickSwitchShortcut: shortcut })
}

/**
 * 清理重复的设置记录（保留最新的一个）
 */
export async function clearDuplicateSettings(): Promise<void> {
  try {
    // 获取所有 id 为 SETTINGS_ID 的记录
    const allDocs = await collection.find({ id: SETTINGS_ID }).fetch()
    
    if (allDocs.length <= 1) {
      return // 没有重复记录
    }
    
    // 找出需要保留的记录（最新的那个）
    const latestDoc = allDocs.sort((a: any, b: any) => {
      // 按 _id 排序，取最新的
      return String(b._id || '').localeCompare(String(a._id || ''))
    })[0]
    
    // 收集需要删除的记录 id
    const idsToDelete: string[] = []
    for (const doc of allDocs) {
      const docId = (doc as any)._id
      if (docId && docId !== latestDoc._id) {
        idsToDelete.push(String(docId))
      }
    }
    
    // 批量删除重复记录
    if (idsToDelete.length > 0) {
      await collection.remove(idsToDelete)
      console.log(`清理了 ${idsToDelete.length} 条重复的设置记录`)
    }
  } catch (error) {
    console.error('清理重复设置记录失败:', error)
  }
}

/**
 * 清空所有设置（删除数据库中的设置记录，重置为默认值）
 */
export async function clearSettings(): Promise<void> {
  try {
    // 获取所有 id 为 SETTINGS_ID 的记录
    const allDocs = await collection.find({ id: SETTINGS_ID }).fetch()
    
    if (allDocs.length > 0) {
      // 收集所有记录的 id
      const idsToDelete: string[] = []
      for (const doc of allDocs) {
        const docId = (doc as any)._id || (doc as any).id
        if (docId) {
          idsToDelete.push(String(docId))
        }
      }
      
      // 批量删除所有设置记录
      if (idsToDelete.length > 0) {
        await collection.remove(idsToDelete)
        console.log(`清空了 ${idsToDelete.length} 条设置记录`)
      }
    }
    
    // 清除缓存
    currentSettingsCache = null
  } catch (error) {
    console.error('清空设置失败:', error)
    throw error
  }
}

